/*
    @file kern_include.cl
    @author Claus Wimmer
    @date 2014-07-19

    Project: secondspace-2
    Licence: LGPL (Lesser GPL)
*/

#define ROW         (get_global_id(0) / _cols)
// Current column.
#define COL         (get_global_id(0) % _cols)
// Begin of the variable indexes.
// First pendulum variable.
#define E    (0)
// Second pendulum variable.
#define H    (1)
// Pendulum coupling factor.
#define VX   (2)
// Energy source.
#define VY   (3)
// End of the variable indexes.
// Variable of the current pixels with a variable index as argument.
#define SELF(ITEM)  (_spaceData[(get_global_id(0)           ) * _varsiz + (ITEM)])
// Begin of the variables of the neighbor pixels.
#define LEFT(ITEM)  (_spaceData[(get_global_id(0)  - 1      ) * _varsiz + (ITEM)])
#define RIGHT(ITEM) (_spaceData[(get_global_id(0)  + 1      ) * _varsiz + (ITEM)])
#define UP(ITEM)    (_spaceData[(get_global_id(0)  - _cols  ) * _varsiz + (ITEM)])
#define DOWN(ITEM)  (_spaceData[(get_global_id(0)  + _cols  ) * _varsiz + (ITEM)])
// End of the variables of the neighbor pixels.
#define BIT         (_spaceBits[(get_global_id(0))])
#define LEFTBIT     (_spaceBits[(get_global_id(0)  - 1      )])
#define RIGHTBIT    (_spaceBits[(get_global_id(0)  + 1      )])
#define UPBIT       (_spaceBits[(get_global_id(0)  - _cols  )])
#define DOWNBIT     (_spaceBits[(get_global_id(0)  + _cols  )])
// Begin of the screen pixel color indexes.
#define RED         (_imgData[4 * (get_global_id(0)) + 2])
#define GREEN       (_imgData[4 * (get_global_id(0)) + 1])
#define BLUE        (_imgData[4 * (get_global_id(0)) + 0])
// End of the screen pixel color indexes.

// Render the pixel.
void show(
    __global float *_spaceData,
    __global int *_spaceBits,
    __global uchar *_imgData,
    __global int *_slider,
    __global uint *_modus,
    const uint _rows,
    const uint _cols,
    const uint _varsiz
    ) {

    // Colour channel values.
    int _r, _g, _b;
    // Current amplitude value.
    float _p = 0.0f;

    switch(_modus[0]){
        case 0: _p = SELF(E) + LEFT(E) + RIGHT(E) + UP(E) + DOWN(E); break;
        case 1: _p = LEFT(H) + LEFT(H) + RIGHT(H) + UP(H) + DOWN(H); break;
        case 2: _p = LEFT(VX); break;
    }
    // Contrast slider.
    if(0 < _slider[0]) {
        _p *= 2 << _slider[0];
    } else {
        _p /= 2 << -_slider[0];
    }
    // Saturate.
    if(1.0f < _p) {
        _p = 1.0f;
    }
    if(-1.0f > _p) {
        _p = -1.0f;
    }
    // Transform to integer.
   _r = _g = _b = (uchar)(((_p) * 127.0f) + 127.0f);
    // Copy to the image data struct.
    RED     = _b;
    GREEN   = _g;
    BLUE    = _r;
    // Show the coordinate's cross.
    if(ROW == _rows / 2 || COL == _cols / 2) {
        RED = 255;
        GREEN = 0;
        BLUE = 0;
    }

    if(BIT){
        RED = 0;
        GREEN = 0;
        BLUE = 255;
    }
}
